package com.itheima.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.bean.*;
import com.itheima.common.BaseContext;
import com.itheima.common.R;
import com.itheima.dao.*;
import com.itheima.dto.OrdersDto;
import com.itheima.exception.CustomException;
import com.itheima.service.OrderDetailService;
import com.itheima.service.OrderService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderDao, Orders> implements OrderService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private ShoppingCartDao shoppingCartDao;

    @Autowired
    private AddressBookDao addressBookDao;

    @Autowired
    private OrderDetailDao orderDetailDao;

    @Autowired
    private OrderDetailService orderDetailService;

    /**
     * 下单
     * @param orders
     */
    @Override
    public void submit(Orders orders) {
        //1.获取登录用户id 根据id查询用户，判断用户是否存在              不存在：提示"请先登录再下单！"
        Long userId = BaseContext.getCurrentId();
        User user = userDao.selectById(userId);
        if(user==null){
            throw new CustomException("请先登录再下单！");
        }

        //2.根据用户id查询购物车列表数据 判断购物车中是否有商品信息        不存在：提示"请先添加购物车再下单！"
        LambdaQueryWrapper<ShoppingCart> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(ShoppingCart::getUserId,userId);
        List<ShoppingCart> carts = shoppingCartDao.selectList(wrapper1);
        if(carts==null || carts.size()==0){
            throw new CustomException("请先添加商品到购物车再下单！");
        }

        //3.根据地址id查询用户地址是否存在                          不存在：提示"请正确填写地址后下单！"
        AddressBook addressBook = addressBookDao.selectById(orders.getAddressBookId());
        if(addressBook==null){
            throw new CustomException("请正确填写地址后下单！");
        }

        //提前生成订单id   使用MyBatisPlus提供的IdWorker提前生成一个订单id 用的规则就是雪花算法
        long orderId = IdWorker.getId();
        //提前声明总金额  原子类型：保证并发环境下数据安全
        AtomicInteger sumAmount = new AtomicInteger(0);

        //4.保存订单详情信息到order_detail表中   将当前用户购物车中的商品数据转存到订单详情表中   ShoppingCart-->OrderDetail
        //遍历当前用户购物车列表数据 将ShoppingCart-->OrderDetail 保存到order_detail表中
        carts.stream().forEach(cart->{
            //创建OrderDetail对象
            OrderDetail orderDetail = new OrderDetail();
            //a.将ShoppingCart对象属性数据  复制到 OrderDetail对象中  注意：只有相同属性的才会复制过去 id属性不需要
            BeanUtils.copyProperties(cart,orderDetail,"id");
            //b.设置当前订单项关联订单id
            orderDetail.setOrderId(orderId);
            //c.计算总金额
            sumAmount.addAndGet((cart.getAmount().multiply(new BigDecimal(cart.getNumber()))).intValue());
            //d.保存到订单详情表
            orderDetailDao.insert(orderDetail);
        });

        //5.保存用户订单基本信息到orders表
        //组装订单信息
        //订单 id
        orders.setId(orderId);
        //订单号 number
        orders.setNumber(UUID.randomUUID().toString());
        //订单状态 status 1待付款，2待派送，3已派送，4已完成，5已取消
        orders.setStatus(2);
        //下单用户id userId
        orders.setUserId(userId);
        //地址id addressBookId  前端传递
        //下单时间 orderTime
        orders.setOrderTime(LocalDateTime.now());
        //结账时间 checkoutTime
        orders.setCheckoutTime(LocalDateTime.now());
        //支付方式 payMethod 1微信，2支付宝   前端传递
        //实收金额  amount
        orders.setAmount(new BigDecimal(sumAmount.get()));
        //备注  remark 前端传递
        //用户名  userName;
        orders.setUserName(user.getName());
        //手机号 phone
        orders.setPhone(addressBook.getPhone());
        //地址 address
        orders.setAddress((addressBook.getProvinceName()==null?"":addressBook.getProvinceName())+
                            (addressBook.getCityName()==null?"":addressBook.getCityName())+
                            (addressBook.getDistrictName()==null?"":addressBook.getDistrictName())+
                            addressBook.getDetail()
                        );
        //收货人 consignee
        orders.setConsignee(addressBook.getConsignee());

        this.save(orders);

        //6.清空当前用户购物车数据
        shoppingCartDao.delete(wrapper1);
    }


    // 移动端查看订单
    @Override
    public Page<OrdersDto> userPage(int page, int pageSize) {
        //分页构造器对象
        Page<Orders> pageInfo = new Page<>(page, pageSize);
        Page<OrdersDto> dtoPage = new Page<>();
        //创建条件查询对象
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        //添加排序条件，根据更新时间降序排序
        queryWrapper.orderByDesc(Orders::getOrderTime);
        this.page(pageInfo, queryWrapper);
        //通过OrderId查寻对应的菜品/套餐
        LambdaQueryWrapper<OrderDetail> wrapper = new LambdaQueryWrapper<>();
        //对OrderDto进行需要的属性赋值
        List<Orders> records = pageInfo.getRecords();
        List<OrdersDto> list = records.stream().map((item) -> {
            OrdersDto ordersDto = new OrdersDto();
            //为orderDetails属性赋值
            //获取订单ID
            Long orderId = item.getId();
            //根据订单ID查询对应的订单明细
            wrapper.eq(OrderDetail::getOrderId, orderId);
            List<OrderDetail> orderDetailList = orderDetailService.list(wrapper);
            BeanUtils.copyProperties(item, ordersDto);
            //对ordersDto的orderDetail属性进行赋值
            ordersDto.setOrderDetails(orderDetailList);
            return ordersDto;
        }).collect(Collectors.toList());
        BeanUtils.copyProperties(pageInfo, dtoPage, "records");
        dtoPage.setRecords(list);
        return dtoPage;
    }
}
